package com.pearlsoft.webapp.core.executor;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.pearlsoft.commons.utils.ClassUtil;
import com.pearlsoft.commons.utils.JsonUtil;
import com.pearlsoft.webapp.core.dataset.DataSet;
import com.pearlsoft.webapp.core.dataset.DataSetFactory;
import com.pearlsoft.webapp.core.dataset.DataSetHandler;
import com.pearlsoft.webapp.core.dataset.DataSetHandlerFactory;
import com.pearlsoft.webapp.core.dataset.Result;
import com.pearlsoft.webapp.core.web.util.MethodUtils;

/**
 * 
 * DataSetExecutor
 * 
 * @Creator haitingr
 * @Create-DateTime 2011-10-25
 */
public class DataSetExecutor extends AbstractExecutor {

    protected static final Log logger = LogFactory.getLog(DataSetExecutor.class);

    protected DataSetFactory dataSetFactory;

    protected DataSetHandlerFactory datasetHandlerFactory;

    protected String encoding = "UTF-8";

    @SuppressWarnings("unchecked")
    public byte[] execute(byte[] message) throws Exception {
        Result result = new Result();
        try {
            logger.debug("dataset request json message--->" + new String(message, "UTF-8"));
            Map<String, Object> map = JsonUtil.toMap(message, encoding);
            String dsname = (String) map.get(DataSet._name_attribute);
            DataSet ds = this.dataSetFactory.create(dsname);

            List<Map<String, Object>> records = (List<Map<String, Object>>) map.get(DataSet._record_attriubte);

            for (Map<String, Object> record : records) {
                ds.newRecord();
                for (String key : record.keySet()) {
                    ds.setValue(key, record.get(key));
                }
            }
            //edit by yehh 20120307 
            List<Map<String, Object>> conditions = (List<Map<String, Object>>) map.get(DataSet._condition_attribute);
            for (Map<String, Object> condition : conditions) {
                ds.addCondition(condition.get(DataSet._condition_fieldName).toString(), condition
                        .get(DataSet._condition_value));
            }

            String handlerName = (String) map.get(DataSet._handler_attribute);

            DataSetHandler handler = this.datasetHandlerFactory.create(handlerName);

            handler.setHttpServletRequest(this.getHttpServletRequest());
            handler.setHttpServletResponse(this.getHttpServletResponse());

            Method method = ClassUtil.getMethodIfAvailable(handler.getClass(), (String) map
                    .get(DataSet._method_attribute), new Class<?>[] { DataSet.class, Result.class });
            //method.invoke(handler, new Object[] { ds, result });
            MethodUtils.invoke(handler, method, new Object[] { ds, result });
            // handler.handler(ds, result);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            result.setSuccess(false);
            result.setStatusCode("301");
            result.setMessage(e.getMessage());
            result.setRecords(null);
            throw new RuntimeException(e);
        }
        logger.debug("result:" + new String(result.toJson(), "UTF-8"));
        return result.toJson();

    }

    public void setDataSetFactory(DataSetFactory datasetFactory) {
        this.dataSetFactory = datasetFactory;
    }

    public void setDataSetHandlerFactory(DataSetHandlerFactory datasetHandlerFactory) {
        this.datasetHandlerFactory = datasetHandlerFactory;
    }

    public void setEncoding(String encoding) {
        this.encoding = encoding;
    }

}
